#include <iostream>
#include <string>
#include <map>
#include <fstream>
#include <sstream>

#include "Sock.hpp"

namespace entocn
{
    class SelectServer
    {
    private:
        int _server_sock;
        std::map<std::string, std::string> _dict;
        std::map<int, std::string> _clients;

        void initDictionary()
        {
            // 英汉互译词典：dict.txt
            // std::ifstream ifs("dict.txt");
            // std::string line;
            // while (std::getline(ifs, line))
            // {
            //     std::istringstream iss(line);
            //     std::string key, value;
            //     iss >> key >> value;
            //     _dict[key] = value;
            // }

            _dict["hello"] = "你好";
        }

        void handleClient(int client_sock)
        {
            char buff[1024];
            ssize_t s = recv(client_sock, buff, sizeof(buff) - 1, 0);
            if (s > 0)
            {
                buff[s] = 0;
                std::string message(buff);

                auto it = _dict.find(message);
                if(it != _dict.end()) {
                    std::string resp = it->second;
                    send(client_sock, resp.c_str(), resp.size(), 0);
                } else {
                    std::string resp = "word not found.";
                    send(client_sock, resp.c_str(), resp.size(), 0);
                }
            }
            else if (s == 0)
            {
                std::cout << "client quit." << std::endl;
                close(client_sock);
                _clients.erase(client_sock);
            }
            else
            {
                perror("recv error");
                close(client_sock);
                _clients.erase(client_sock);
            }
        }

    public:
        SelectServer(uint16_t port)
        {
            _server_sock = Sock::Socket();
            Sock::Bind(_server_sock, port);
            Sock::Listen(_server_sock);
            initDictionary();
        }

        // void start()
        // {
        //     fd_set readfds;
        //     while (true)
        //     {
        //         FD_ZERO(&readfds); // 每次循环都要清空
        //         FD_SET(_server_sock, &readfds); // 将服务器套接字加入集合

        //         int max_fd = _server_sock; // 初始化最大文件描述符

        //         for(const auto& client : _clients) {
        //             FD_SET(client.first, &readfds); // 将客户端套接字加入集合
        //         }

        //         int activity = select(max_fd + 1, &readfds, nullptr, nullptr, nullptr);
        //         if (activity < 0)
        //         {
        //             perror("select error");
        //             break;
        //         }

        //         if (FD_ISSET(_server_sock, &readfds))
        //         {
        //             std::string clientIP;
        //             uint16_t clientPort;
        //             int new_client_sock = Sock::Accept(_server_sock, &clientIP, &clientPort);
        //             _clients[new_client_sock] = clientIP;

        //             if( new_client_sock > max_fd) {
        //                 max_fd = new_client_sock;
        //             }

        //             std::cout << "new client: " << clientIP << ":" << clientPort << std::endl;
        //         }

        //         for(auto& client : _clients) 
        //         {
        //             if(FD_ISSET(client.first, &readfds)) {
        //                 handleClient(client.first);
        //             }
        //         }
        //     }
        // }
        void start()
        {
            fd_set readfds;
            while (true)
            {
                FD_ZERO(&readfds);
                FD_SET(_server_sock, &readfds);

                int max_fd = _server_sock;
                for(const auto& client : _clients) {
                    FD_SET(client.first, &readfds);
                    if (client.first > max_fd) {
                        max_fd = client.first;
                    }
                }

                int activity = select(max_fd + 1, &readfds, nullptr, nullptr, nullptr);
                if (activity < 0)
                {
                    perror("select error");
                    break;
                }

                if (FD_ISSET(_server_sock, &readfds))
                {
                    std::string clientIP;
                    uint16_t clientPort;
                    int new_client_sock = Sock::Accept(_server_sock, &clientIP, &clientPort);
                    if (new_client_sock < 0) {
                        perror("accept error");
                        continue;
                    }
                    _clients[new_client_sock] = clientIP;

                    std::cout << "new client: " << clientIP << ":" << clientPort << std::endl;
                }

                for(auto it = _clients.begin(); it != _clients.end();)
                {
                    if(FD_ISSET(it->first, &readfds)) {
                        handleClient(it->first);
                        it = _clients.erase(it); // 断开连接移除
                    }
                    else {
                        ++it;
                    }
                }
            }
        }

    };
}